<template>
  <a-drawer
    v-model:visible="visible"
    :title="title"
    :mask-closable="false"
    :esc-to-close="false"
    :width="width >= 1850 ? 1850 : '100%'"
    @before-ok="save"
    @close="reset"
  >
    <a-tabs v-model:active-key="activeKey">
      <a-tab-pane key="1" title="生成配置">
        <GiForm ref="formRef" v-model="form" :columns="formColumns" />
      </a-tab-pane>
      <a-tab-pane key="2" title="字段配置">
        <GiTable
          row-key="tableName"
          :data="dataList"
          :columns="columns"
          :loading="loading"
          :scroll="{ x: '100%', y: 800, minWidth: 900 }"
          :pagination="false"
          :draggable="{ type: 'handle', width: 40 }"
          :disabled-tools="['setting', 'refresh']"
          :disabled-column-keys="['tableName']"
          @change="handleChangeSort"
        >
          <template #toolbar-left>
            <a-popconfirm
              content="是否确定同步最新数据表结构？同步后只要不点击确定保存，则不影响原有配置数据。"
              type="warning"
              @ok="handleRefresh(form.tableName)"
            >
              <a-tooltip content="同步最新数据表结构">
                <a-button
                  type="primary"
                  status="success"
                  size="small"
                  title="同步"
                  :disabled="dataList.length !== 0"
                >
                  <template #icon><icon-sync /></template>同步
                </a-button>
              </a-tooltip>
            </a-popconfirm>
          </template>
          <template #fieldName="{ record }">
            <a-input v-model="record.fieldName" />
          </template>
          <template #fieldType="{ record }">
            <a-select
              v-model="record.columnType"
              placeholder="请选择字段类型"
              allow-search
              allow-create
              :error="!record.columnType"
            >
              <a-option value="String">String</a-option>
              <a-option value="Integer">Integer</a-option>
              <a-option value="Long">Long</a-option>
              <a-option value="Float">Float</a-option>
              <a-option value="Double">Double</a-option>
              <a-option value="Boolean">Boolean</a-option>
              <a-option value="BigDecimal">BigDecimal</a-option>
              <a-option value="LocalDate">LocalDate</a-option>
              <a-option value="LocalTime">LocalTime</a-option>
              <a-option value="LocalDateTime">LocalDateTime</a-option>
            </a-select>
          </template>
          <template #columnName="{ record }">
            <a-input v-model="record.columnName" />
          </template>
          <template #comment="{ record }">
            <a-input v-model="record.comment" />
          </template>
          <template #goType="{ record }">
            <a-select
              v-model="record.goType"
              placeholder="请选择"
            >
              <a-option value="int64">int64</a-option>
              <a-option value="string">string</a-option>
              <a-option value="int">int</a-option>
              <a-option value="bool">bool</a-option>
            </a-select>
          </template>
          <template #goField="{ record }">
            <a-input v-model="record.goField" />
          </template>
          <template #jsonField="{ record }">
            <a-input v-model="record.jsonField" />
          </template>

          <template #showInList="{ record }">
            <a-checkbox v-model="record.showInList" value="true" />
          </template>
          <template #showInForm="{ record }">
            <a-checkbox v-model="record.showInForm" value="true" />
          </template>
          <template #isRequired="{ record }">
            <a-checkbox v-if="record.showInForm" v-model="record.isRequired" value="true" />
            <a-checkbox v-else disabled />
          </template>
          <template #showInQuery="{ record }">
            <a-checkbox v-model="record.showInQuery" value="true" />
          </template>
          <template #formType="{ record }">
            <a-select
              v-if="record.showInForm || record.showInQuery"
              v-model="record.formType"
              :options="form_type_enum"
              :default-value="1"
              placeholder="请选择表单类型"
            />
            <span v-else>无需设置</span>
          </template>
          <template #queryType="{ record }">
            <a-select
              v-if="record.showInQuery"
              v-model="record.queryType"
              :options="query_type_enum"
              :default-value="1"
              placeholder="请选择查询方式"
            />
            <span v-else>无需设置</span>
          </template>
          <template #dictCode="{ record }">
            <a-select
              v-model="record.dictCode"
              :options="dictList"
              placeholder="请选择字典类型"
              allow-search
              allow-clear
            />
          </template>
        </GiTable>
        <a-alert v-if="dataList.length > 0" type="warning">
          表字段中的id、create_by、update_by、created_at、updated_at、deleted_at的字段在此列表中已经隐藏
        </a-alert>
      </a-tab-pane>
    </a-tabs>
  </a-drawer>
</template>

<script setup lang="ts">
import type { TableInstance } from '@arco-design/web-vue'
import { Message } from '@arco-design/web-vue'
import { useWindowSize } from '@vueuse/core'
import { type FieldConfigResp, type GeneratorConfigResp, UpdateGenConfig, getGenConfig, listFieldConfig } from '@/apis/code/generator'
import type { LabelValueState } from '@/types/global'
import { type ColumnItem, GiForm } from '@/components/GiForm'
import { useResetReactive } from '@/hooks'
import { listDict } from '@/apis/system/dict'

const emit = defineEmits<{
  (e: 'save-success'): void
}>()

const { width } = useWindowSize()

const title = ref('')
const visible = ref(false)
const activeKey = ref('1')
const formRef = ref<InstanceType<typeof GiForm>>()
// const { form_type_enum, query_type_enum } = useDict('form_type_enum', 'query_type_enum')
const dictList = ref<LabelValueState[]>([])

const [form, resetForm] = useResetReactive({
  isOverride: false,
  tableName: '',
})
interface LabelValueItem { label: string, value: string, disabled: boolean, color?: string }

/** @desc 表情表单字段 */
const tplCategoryList: LabelValueItem[] = [
  { label: '关系表（增删改查）', value: 'crud', disabled: false, color: 'green' },
  { label: '创建表（增删改查）', value: 'mcrud', disabled: true, color: 'red' },
  { label: '树表（增删改查）', value: 'tree', disabled: true, color: 'blue' },
]
const form_type_enum: LabelValueItem[] = [
  { label: '文本框', value: 'input', disabled: false, color: 'green' },
  { label: '下拉框', value: 'select', disabled: false, color: 'red' },
  { label: '单选框', value: 'radio', disabled: false, color: 'blue' },
  { label: '文件选择', value: 'file', disabled: true, color: 'blue' },
  { label: '复选框', value: 'checkbox', disabled: false, color: 'blue' },
  { label: '日期控件', value: 'raddatetimeio', disabled: false, color: 'blue' },
  { label: '文本域', value: 'textarea', disabled: false, color: 'blue' },
]

const query_type_enum: LabelValueItem[] = [
  { label: '=', value: 'EQ', disabled: false, color: 'green' },
  { label: '!=', value: 'NE', disabled: false, color: 'red' },
  { label: '>', value: 'GT', disabled: false, color: 'blue' },
  { label: '>=', value: 'GTE', disabled: false, color: 'blue' },
  { label: '<', value: 'LT', disabled: false, color: 'blue' },
  { label: '<=', value: 'LTE', disabled: false, color: 'blue' },
  { label: 'Like', value: 'LIKE', disabled: false, color: 'blue' },
  { label: 'BetWeen', value: 'BETWEEN', disabled: true, color: 'blue' },
]

const formColumns: ColumnItem[] = reactive([
  {
    label: '数据表名称',
    field: 'tableName',
    type: 'input',
    tooltip: '数据库表名称，针对gorm对应的table()使用，⚠️这里必须是蛇形结构" field="tableName',
    required: true,
    props: {
      maxLength: 100,
    },
    rules: [{ required: true, message: '请输入表名名称' }],
  },
  {
    label: '菜单名称',
    field: 'tableComment',
    type: 'input',
    tooltip: '同步的数据库表名称，生成配置数据时，用作中文菜单名称',
    required: true,
    props: {
      maxLength: 100,
    },
    rules: [{ required: true, message: '请输入菜单名称' }],
  },
  {
    label: 'Go结构体名称',
    field: 'className',
    type: 'input',
    tooltip: '结构体模型名称，代码中的struct名称定义使用',
    required: true,
    props: {
      maxLength: 100,
    },
    rules: [{ required: true, message: '请输入Go结构体名称' }],
  },
  {
    label: '作者名称',
    field: 'functionAuthor',
    type: 'input',
    required: true,
    props: {
      maxLength: 100,
    },
  },
  {
    label: '生成模板',
    field: 'tplCategory',
    type: 'select',
    props: {
      placeholder: '生成代码的目录，例如：/src/main/java/',
      maxLength: 100,
      options: tplCategoryList,
    },
    rules: [{ required: true, message: '请输入生成目录' }],
  },
  {
    label: '包名',
    field: 'packageName',
    type: 'input',
    props: {
      placeholder: '包名，例如：在app文件夹下将该功能发到那个应用中，默认：app',
      maxLength: 60,
      showWordLimit: true,
    },
    rules: [{ required: true, message: '请输入所属包名' }],
  },
  {
    label: '功能描述',
    field: 'functionName',
    type: 'input',
    props: {
      placeholder: '同步的数据库表备注，用作类描述，例如：用户" field="functionName',
      maxLength: 60,
    },
    rules: [{ required: true, message: '请输入功能描述' }],
  },
  {
    label: '备注',
    field: 'remark',
    type: 'textarea',
    props: {
      placeholder: '请输入描述',
      maxLength: 200,
      showWordLimit: true,

    },
  },
])

const dataList = ref<FieldConfigResp[]>([])
const loading = ref(false)
// 查询列表数据
const getDataList = async (tableName: string, requireSync: boolean) => {
  try {
    loading.value = true
    const { data } = await listFieldConfig(tableName, requireSync)
    dataList.value = data
  } finally {
    loading.value = false
  }
}

// Table 字段配置
const columns: TableInstance['columns'] = [
  { title: '名称', slotName: 'columnName' },
  { title: '描述', slotName: 'comment', width: 170 },
  { title: '类型', slotName: 'fieldType' },

  { title: 'go类型', slotName: 'goType', width: 130, ellipsis: true, tooltip: true },
  { title: 'go属性', slotName: 'goField', width: 130, ellipsis: true, tooltip: true },
  { title: 'json属性', slotName: 'jsonField', width: 120, ellipsis: true, tooltip: true },
  { title: '列表', slotName: 'showInList', width: 60, align: 'center' },
  { title: '表单', slotName: 'showInForm', width: 60, align: 'center' },
  { title: '必填', slotName: 'isRequired', width: 60, align: 'center' },
  { title: '查询', slotName: 'showInQuery', width: 60, align: 'center' },
  { title: '表单类型', slotName: 'formType' },
  { title: '查询方式', slotName: 'queryType' },
  { title: '关联字典', slotName: 'dictCode' },
]

// 重置
const reset = () => {
  formRef.value?.formRef?.resetFields()
  resetForm()
}

// 同步
const handleRefresh = async (tableName: string) => {
  await getDataList(tableName, true)
}

// 拖拽排序
const handleChangeSort = (newDataList: FieldConfigResp[]) => {
  dataList.value = newDataList
}

// 保存
const save = async () => {
  try {
    const isInvalid = await formRef.value?.formRef?.validate()
    if (isInvalid) {
      activeKey.value = '1'
      return false
    }
    // await saveGenConfig(form.tableName, {
    //   genConfig: form,
    //   fieldConfigs: dataList.value,
    // } as GeneratorConfigResp)
    form.columns = dataList.value
    await UpdateGenConfig(form)

    Message.success('保存成功')
    emit('save-success')
    return true
  } catch (error) {
    return false
  }
}

// 打开
const onOpen = async (tableName: string, comment: string) => {
  reset()
  comment = comment ? `（${comment}）` : ' '
  title.value = `${tableName}${comment}配置`
  // 查询生成配置
  const { data } = await getGenConfig(tableName)
  Object.assign(form, data)
  form.isOverride = form.isOverride || false
  visible.value = true
  // 查询字段配置
  // await getDataList(tableName, false)
  dataList.value = data.columns
  // const res = await listFieldConfigDict()
  // dictList.value = res.data

  const dictRes = await listDict()
  dictList.value = dictRes.data.map((item) => ({
    label: item.name,
    value: item.code,
  }))
}

defineExpose({ onOpen })
</script>

<style scoped lang="scss">
:deep(.gen-config.arco-form) {
  width: 50%;
}
</style>
